﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

using DapperExtensions;
using LmgCMS.Model;
namespace LmgCMS.Service
{
    ///<summary>
    ///多对多关系集中映射
    ///</summary>
    public interface IRelevanceService : IRepository<Relevance>
    {
        /// <summary>
        /// 添加关联
        /// <para>比如给用户分配资源，那么firstId就是用户ID，secIds就是资源ID列表</para>
        /// </summary>
        /// <param name="type">关联的类型，如Define.USERRESOURCE</param>
        void Assign(AssignReq request);
        /// <summary>
        /// 取消关联
        /// </summary>
        /// <param name="type">关联的类型，如Define.USERRESOURCE</param>
        /// <param name="firstId">The first identifier.</param>
        /// <param name="secIds">The sec ids.</param>
        void UnAssign(AssignReq req);
        /// <summary>
        /// 分配数据字段权限
        /// </summary>
        /// <param name="request"></param>
        void AssignData(AssignDataReq request);
        /// <summary>
        /// 取消数据字段分配
        /// </summary>
        /// <param name="request"></param>
        void UnAssignData(AssignDataReq request);
        /// <summary>
        /// 为角色分配用户，需要统一提交，会删除以前该角色的所有用户
        /// </summary>
        /// <param name="request"></param>
        void AssignRoleUsers(AssignRoleUsers request);
        /// <summary>
        /// 为部门分配用户，需要统一提交，会删除以前该部门的所有用户
        /// </summary>
        /// <param name="request"></param>
        void AssignOrgUsers(AssignOrgUsers request);
        List<string> FindAll(string key,bool returnSecondIds,params string[] ids);
        List<string> FindAll(string key,string firstId,string secondId);
    }
    ///<summary>
    ///多对多关系集中映射
    ///</summary>
    public partial class RelevanceService : BaseRepository<Relevance>, IRelevanceService
    {
        /// <summary>
        /// 添加关联
        /// <para>比如给用户分配资源，那么firstId就是用户ID，secIds就是资源ID列表</para>
        /// </summary>
        /// <param name="type">关联的类型，如Define.USERRESOURCE</param>
        public void Assign(AssignReq request)
        {
            Assign(request.type, request.secIds.ToLookup(u => request.firstId));
        }
        /// <summary>
        /// 添加关联，需要人工删除以前的关联
        /// </summary>
        /// <param name="key"></param>
        /// <param name="idMaps"></param>
        public void Assign(string key, ILookup<string, string> idMaps)
        {
            this.Add((from sameVals in idMaps
                           from value in sameVals
                           select new Relevance
                           {
                               Key = key,
                               FirstId = sameVals.Key,
                               SecondId = value,
                               AddTime = DateTime.Now
                           }).ToList());
        }
        /// <summary>
        /// 取消关联
        /// </summary>
        /// <param name="type">关联的类型，如Define.USERRESOURCE</param>
        /// <param name="firstId">The first identifier.</param>
        /// <param name="secIds">The sec ids.</param>
        public void UnAssign(AssignReq req)
        {
            if (req.secIds == null || req.secIds.Length == 0)
            {
                DeleteBy(req.type, req.firstId);
            }
            else
            {
                DeleteBy(req.type, req.secIds.ToLookup(u => req.firstId));
            }
        }
        public void DeleteBy(string key, params string[] firstIds)
        {
            string sqlWhere = " [Key] ='" + key + "' AND FirstId in(" + firstIds.ToSql(false) + ")";
            DeleteWhere(sqlWhere);
        }
        /// <summary>
        /// 删除关联
        /// </summary>
        /// <param name="key">关联标识</param>
        /// <param name="idMaps">关联的&lt;firstId, secondId&gt;数组</param>
        private void DeleteBy(string key, ILookup<string, string> idMaps)
        {
            foreach (var sameVals in idMaps)
            {
                foreach (var value in sameVals)
                {
                    string sqlWhere = " [Key] ='" + key + "' AND FirstId='"+ sameVals.Key + "' AND SecondId='" +value+"'";
                    DeleteWhere(sqlWhere);
                }
            }
        }
        /// <summary>
        /// 根据关联表的一个键获取另外键的值
        /// </summary>
        /// <param name="key">映射标识</param>
        /// <param name="returnSecondIds">返回的是否为映射表的第二列，如果不是则返回第一列</param>
        /// <param name="ids">已知的ID列表</param>
        /// <returns>List&lt;System.String&gt;.</returns>
        public List<string> FindAll(string key, bool returnSecondIds, params string[] ids)
        {
            if (returnSecondIds)
            {
                string sqlwhere = $"[key]='{key}' and [FirstId] in({ids.ToSql(false)})";
                return FindAll(sqlwhere).Select(u => u.SecondId).ToList();
            }
            else
            {
                string sqlwhere = $"[key]='{key}' and [SecondId] in({ids.ToSql(false)})";
                return FindAll(sqlwhere).Select(u => u.FirstId).ToList();
            }
        }

        /// <summary>
        /// 根据key ,firstId,secondId获取thirdId
        /// </summary>
        /// <param name="key"></param>
        /// <param name="firstId"></param>
        /// <param name="secondId"></param>
        /// <returns></returns>
        public List<string> FindAll(string key, string firstId, string secondId)
        {
            string sqlwhere = $"[key]='{key}' and FirstId='{firstId}' and SecondId='{secondId}'";
            return FindAll(sqlwhere).Select(u => u.ThirdId).ToList();
        }

        /// <summary>
        /// 分配数据字段权限
        /// </summary>
        /// <param name="request"></param>
        public void AssignData(AssignDataReq request)
        {
            var relevances = new List<Relevance>();
            foreach (var requestProperty in request.Properties)
            {
                relevances.Add(new Relevance
                {
                    Key = Define.ROLEDATAPROPERTY,
                    FirstId = request.RoleId,
                    SecondId = request.ModuleCode,
                    ThirdId = requestProperty,
                    AddTime = DateTime.Now
                });
            }
            Add(relevances);
        }

        /// <summary>
        /// 取消数据字段分配
        /// </summary>
        /// <param name="request"></param>
        public void UnAssignData(AssignDataReq request)
        {
            if (request.Properties == null || request.Properties.Length == 0)
            {
                if (string.IsNullOrEmpty(request.ModuleCode))  //模块为空，直接把角色的所有授权删除
                {
                    DeleteBy(Define.ROLEDATAPROPERTY, request.RoleId);
                }
                else  //把角色的某一个模块权限全部删除
                {
                    DeleteBy(Define.ROLEDATAPROPERTY, new[] { request.ModuleCode }.ToLookup(u => request.RoleId));
                }
            }
            else  //按具体的id删除
            {
                foreach (var property in request.Properties)
                {
                    string sqlWhere = " [Key] ='" + Define.ROLEDATAPROPERTY 
                        + "' AND FirstId='" + request.RoleId
                        + "' AND SecondId='" + request.ModuleCode
                        + "' AND ThirdId='" + property + "'";
                    DeleteWhere(sqlWhere);
                }
            }
        }
        /// <summary>
        /// 为角色分配用户，需要统一提交，会删除以前该角色的所有用户
        /// </summary>
        /// <param name="request"></param>
        public void AssignRoleUsers(AssignRoleUsers request)
        {
            if (request.IsDelete)
            {
                //删除以前的所有用户
                string sqlWhere = " [Key] ='" + Define.USERROLE + "' AND SecondId='" + request.RoleId + "'";
                DeleteWhere(sqlWhere);
            }
            //批量分配用户角色
           Add((from firstId in request.UserIds
                      select new Relevance
                      {
                          Key = Define.USERROLE,
                          FirstId = firstId,
                          SecondId = request.RoleId,
                          AddTime = DateTime.Now
                      }).ToList());
        }

        /// <summary>
        /// 为部门分配用户，需要统一提交，会删除以前该部门的所有用户
        /// </summary>
        /// <param name="request"></param>
        public void AssignOrgUsers(AssignOrgUsers request)
        {
            if (request.IsDelete)
            {
                //删除以前的所有用户
                string sqlWhere = " [Key] ='" + Define.USERORG + "' AND SecondId='" + request.OrgId + "'";
                DeleteWhere(sqlWhere);
            }
            //批量分配用户角色
            Add((from firstId in request.UserIds
                      select new Relevance
                      {
                          Key = Define.USERORG,
                          FirstId = firstId,
                          SecondId = request.OrgId,
                          AddTime = DateTime.Now
                      }).ToList());
        }
    }
}

